package com.derbysoft.synxisadapter.action.settings.hotel;

import com.derbysoft.core.LimitedList;
import com.derbysoft.synxisadapter.action.DMXAbstractAction;
import com.derbysoft.synxisadapter.commons.exception.HotelNotFoundException;
import com.derbysoft.synxisadapter.commons.model.Hotel;
import com.derbysoft.synxisadapter.commons.repository.HotelRepository;
import com.derbysoft.synxisadapter.commons.repository.impl.HotelCondition;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * User: jason
 * Date: 2013-01-22
 */
public class DMXAction extends DMXAbstractAction {
    private static final String SYNXIS = "SYNXIS";

    @Autowired
    private HotelRepository hotelRepository;

    private HotelCondition condition;

    private String hotels;

    private String disableHotelCodes;

    private String deleteHotelCode;

    @Action("dmxQueryHotel")
    public String dmxQuery() {
        try {
            LimitedList<Hotel> limitedList = hotelRepository.findByCondition(condition, createLimit());
            return populateSucceededJsonResult(dmxPaging(limitedList, super.getPage(), limitedList.getTotalcount()));
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxImportHotels")
    public String importHotels() {
        try {
            if (StringUtils.isBlank(hotels)) {
                return populateSucceededJsonResult("nothing to import.");
            }
            Map<String, Hotel> HotelMap = new HashMap<String, Hotel>();
            StringBuilder builder = new StringBuilder();
            String[] lines = hotels.replace("\r\n", "\n").split("\n");
            for (int lineNumber = 0; lineNumber < lines.length; lineNumber++) {
                String[] columns = lines[lineNumber].split("\\|");
                if (columns == null || columns.length != 2) {
                    builder.append(String.format("<span style=\"color: #ff0000;font-family:Consolas;font-weight: bold;\">[ %d ]. error line :[ %s ]</span>", lineNumber + 1, lines[lineNumber])).append("<br>");
                    continue;
                }
                String[] trimmedColumns = trimAll(columns);
                String hotelId = trimmedColumns[0];
                String passport = trimmedColumns[0];
                String hotelName = trimmedColumns[1];
                Hotel loadByCode = hotelRepository.findById(hotelId);
                if (loadByCode != null) {
                    builder.append(String.format("<span style=\"color: #ff0000;font-family:Consolas;font-weight: bold;\"> HotelId [ %s ] has been existed !!</span>", hotelId)).append("<br>");
                    continue;
                }

                Hotel newMapping = new Hotel();
                newMapping.setId(hotelId);
                newMapping.setPassport(passport);
                newMapping.setName(hotelName);
                newMapping.setProviderName(SYNXIS);
                newMapping.setProviderPassport(SYNXIS);
                newMapping.setStatus(Hotel.Status.ENABLED);
                HotelMap.put(hotelId, newMapping);
                builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">[ %s ] : success !!</span>", hotelId)).append("<br>");
            }
            builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">-------------  total:[%d], success:[%d] -------------</span>", lines.length, HotelMap.values().size())).append("<br>");
            hotelRepository.saveAll(new ArrayList<Hotel>(HotelMap.values()));
            return populateSucceededJsonResult(builder.toString());
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxBatchDisable")
    public String dmxBatchDisable() {
        try {
            if (StringUtils.isBlank(disableHotelCodes)) {
                return populateSucceededJsonResult("nothing to disable.");
            }
            Map<String, Hotel> HotelMap = new HashMap<String, Hotel>();
            StringBuilder builder = new StringBuilder();
            String[] hotelCodes = StringUtils.split(disableHotelCodes, " ");
            for (String hotelCode : hotelCodes) {
                Hotel existed = hotelRepository.findById(hotelCode);
                if (existed == null) {
                    builder.append(String.format("<span style=\"color: #ff0000;font-family:Consolas;font-weight: bold;\"> Hotel not found :[ %s ] !!</span>", hotelCode)).append("<br>");
                    continue;
                }
                builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">[ %s ]: disable done !!</span>", hotelCode)).append("<br>");
                HotelMap.put(hotelCode, existed);
            }
            hotelRepository.disableAll(new ArrayList<Hotel>(HotelMap.values()));
            builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">-------------  total:[%d], success:[%d] -------------</span>", hotelCodes.length, HotelMap.values().size())).append("<br>");
            return populateSucceededJsonResult(builder.toString());
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxDeleteHotel")
    public String dmxDeleteHotel() {
        try {
            if (StringUtils.isBlank(deleteHotelCode)) {
                return populateSucceededJsonResult("hotel code must be not null.");
            }
            Hotel existed = hotelRepository.findById(deleteHotelCode);
            if (existed == null) {
                throw new HotelNotFoundException(deleteHotelCode);
            }
            hotelRepository.delete(existed);
            return populateSucceededJsonResult(String.format("delete done [%s].", deleteHotelCode));
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxLoadHotel")
    public String dmxLoadHotel() {
        try {
            if (condition == null || StringUtils.isBlank(condition.getId())) {
                return populateSucceededJsonResult("hotel code must be not null !");
            }
            Hotel existed = hotelRepository.findById(condition.getId());
            if (existed == null) {
                throw new HotelNotFoundException(condition.getId());
            }
            return populateSucceededJsonResult(existed);
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxUpdateHotel")
    public String dmxUpdateHotel() {
        try {
            if (condition == null) {
                return populateSucceededJsonResult("hotel must be not null !");
            }
            Hotel existed = hotelRepository.findById(condition.getId());
            if (existed == null) {
                throw new HotelNotFoundException(condition.getId());
            }
            existed.setPassport(condition.getPassport());
            existed.setName(condition.getName());
            existed.setStatus(condition.getStatus());
            hotelRepository.save(existed);
            return populateSucceededJsonResult(existed);
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    private String[] trimAll(String[] columns) {
        String[] newColumns = new String[columns.length];
        for (int i = 0; i < columns.length; i++) {
            newColumns[i] = StringUtils.trim(columns[i]);
        }
        return newColumns;
    }

    public String getDeleteHotelCode() {
        return deleteHotelCode;
    }

    public void setDeleteHotelCode(String deleteHotelCode) {
        this.deleteHotelCode = deleteHotelCode;
    }

    public String getDisableHotelCodes() {
        return disableHotelCodes;
    }

    public void setDisableHotelCodes(String disableHotelCodes) {
        this.disableHotelCodes = disableHotelCodes;
    }

    public HotelCondition getCondition() {
        return condition;
    }

    public void setCondition(HotelCondition condition) {
        this.condition = condition;
    }

    public String getHotels() {
        return hotels;
    }

    public void setHotels(String hotels) {
        this.hotels = hotels;
    }
}
